<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>语音识别自动测试</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        
        .container {
            background: white;
            padding: 30px;
            border-radius: 10px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            margin-bottom: 20px;
        }
        
        h1 {
            color: #333;
            border-bottom: 3px solid #007bff;
            padding-bottom: 10px;
        }
        
        h2 {
            color: #555;
            margin-top: 30px;
        }
        
        .form-group {
            margin-bottom: 20px;
        }
        
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: 600;
            color: #555;
        }
        
        input[type="text"], input[type="number"], input[type="file"], textarea, select {
            width: 100%;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 5px;
            font-size: 14px;
            box-sizing: border-box;
        }
        
        textarea {
            height: 100px;
            resize: vertical;
        }
        
        .btn {
            background-color: #007bff;
            color: white;
            padding: 12px 24px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 16px;
            margin-right: 10px;
            margin-bottom: 10px;
        }
        
        .btn:hover {
            background-color: #0056b3;
        }
        
        .btn-success {
            background-color: #28a745;
        }
        
        .btn-success:hover {
            background-color: #1e7e34;
        }
        
        .btn-warning {
            background-color: #ffc107;
            color: #333;
        }
        
        .btn-warning:hover {
            background-color: #e0a800;
        }
        
        .results {
            margin-top: 20px;
            padding: 20px;
            background-color: #f8f9fa;
            border-radius: 5px;
            border-left: 4px solid #007bff;
        }
        
        .success {
            border-left-color: #28a745;
            background-color: #d4edda;
        }
        
        .error {
            border-left-color: #dc3545;
            background-color: #f8d7da;
        }
        
        .audio-file-list {
            max-height: 300px;
            overflow-y: auto;
            border: 1px solid #ddd;
            border-radius: 5px;
            padding: 10px;
        }
        
        .audio-file-item {
            padding: 10px;
            border-bottom: 1px solid #eee;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        
        .audio-file-item:last-child {
            border-bottom: none;
        }
        
        .test-result {
            margin: 10px 0;
            padding: 15px;
            border-radius: 5px;
            border: 1px solid #ddd;
        }
        
        .test-result.success {
            background-color: #d4edda;
            border-color: #c3e6cb;
        }
        
        .test-result.failure {
            background-color: #f8d7da;
            border-color: #f5c6cb;
        }
        
        .loading {
            display: none;
            text-align: center;
            padding: 20px;
        }
        
        .spinner {
            border: 4px solid #f3f3f3;
            border-top: 4px solid #3498db;
            border-radius: 50%;
            width: 40px;
            height: 40px;
            animation: spin 2s linear infinite;
            margin: 0 auto 10px;
        }
        
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        
        .two-column {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 20px;
        }
        
        @media (max-width: 768px) {
            .two-column {
                grid-template-columns: 1fr;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>🎵 语音识别自动测试系统</h1>
        <p>这个工具可以帮助您测试阿里云实时语音识别的功能，上传音频文件并验证识别结果。</p>
    </div>

    <div class="two-column">
        <!-- 左侧：文件管理 -->
        <div class="container">
            <h2>📁 测试音频文件管理</h2>
            
            <!-- 上传音频文件 -->
            <div class="form-group">
                <label for="audioFile">上传音频文件 (WAV/MP3/M4A):</label>
                <input type="file" id="audioFile" accept=".wav,.mp3,.m4a">
            </div>
            
            <div class="form-group">
                <label for="expectedText">期望识别文本:</label>
                <textarea id="expectedText" placeholder="输入期望的识别结果文本..."></textarea>
            </div>
            
            <button class="btn" onclick="uploadAudioFile()">📤 上传文件</button>
            <button class="btn btn-warning" onclick="loadAudioFiles()">🔄 刷新文件列表</button>
            
            <!-- 文件列表 -->
            <h3>可用的测试音频文件:</h3>
            <div id="audioFileList" class="audio-file-list">
                <p>正在加载...</p>
            </div>
        </div>

        <!-- 右侧：测试执行 -->
        <div class="container">
            <h2>🧪 测试执行</h2>
            
            <!-- 单个测试 -->
            <h3>单个文件测试</h3>
            <div class="form-group">
                <label for="testAudioFile">选择音频文件:</label>
                <select id="testAudioFile">
                    <option value="">请选择音频文件</option>
                </select>
            </div>
            
            <div class="form-group">
                <label for="testExpectedText">期望文本:</label>
                <input type="text" id="testExpectedText" placeholder="输入期望的识别结果">
            </div>
            
            <div class="form-group">
                <label for="chunkSize">音频块大小 (bytes):</label>
                <input type="number" id="chunkSize" value="3200" min="1024" max="8192">
            </div>
            
            <div class="form-group">
                <label for="intervalMs">发送间隔 (ms):</label>
                <input type="number" id="intervalMs" value="200" min="50" max="1000">
            </div>
            
            <button class="btn" onclick="runSingleTest()">🚀 执行单个测试</button>
            <button class="btn btn-success" onclick="runPresetTest()">⚡ 执行预设测试</button>
        </div>
    </div>

    <!-- 测试结果显示 -->
    <div class="container">
        <h2>📊 测试结果</h2>
        
        <div id="loading" class="loading">
            <div class="spinner"></div>
            <p>正在执行测试，请稍候...</p>
        </div>
        
        <div id="testResults"></div>
    </div>

    <script>
        const API_BASE = '/api/voice/test';
        
        // 页面加载时初始化
        window.onload = function() {
            loadAudioFiles();
        };
        
        // 上传音频文件
        async function uploadAudioFile() {
            const fileInput = document.getElementById('audioFile');
            const expectedText = document.getElementById('expectedText').value;
            
            if (!fileInput.files[0]) {
                alert('请选择音频文件');
                return;
            }
            
            const formData = new FormData();
            formData.append('file', fileInput.files[0]);
            if (expectedText) {
                formData.append('expectedText', expectedText);
            }
            
            try {
                showLoading(true);
                const response = await fetch(`${API_BASE}/upload-audio`, {
                    method: 'POST',
                    body: formData
                });
                
                const result = await response.json();
                
                if (result.success) {
                    showResults([{
                        type: 'success',
                        title: '文件上传成功',
                        content: `文件: ${result.audioFileInfo.filename}<br>大小: ${result.audioFileInfo.size} bytes`
                    }]);
                    
                    // 清空表单
                    fileInput.value = '';
                    document.getElementById('expectedText').value = '';
                    
                    // 刷新文件列表
                    loadAudioFiles();
                } else {
                    showResults([{
                        type: 'error',
                        title: '上传失败',
                        content: result.message
                    }]);
                }
            } catch (error) {
                showResults([{
                    type: 'error',
                    title: '上传失败',
                    content: error.message
                }]);
            } finally {
                showLoading(false);
            }
        }
        
        // 加载音频文件列表
        async function loadAudioFiles() {
            try {
                const response = await fetch(`${API_BASE}/audio-files`);
                const files = await response.json();
                
                const listElement = document.getElementById('audioFileList');
                const selectElement = document.getElementById('testAudioFile');
                
                if (files.length === 0) {
                    listElement.innerHTML = '<p>没有找到测试音频文件</p>';
                    selectElement.innerHTML = '<option value="">没有可用的音频文件</option>';
                } else {
                    // 更新文件列表显示
                    listElement.innerHTML = files.map(file => `
                        <div class="audio-file-item">
                            <div>
                                <strong>${file.filename}</strong><br>
                                <small>${formatFileSize(file.size)} - ${new Date(file.lastModified).toLocaleString()}</small>
                            </div>
                            <button class="btn" onclick="selectFileForTest('${file.filename}')">选择测试</button>
                        </div>
                    `).join('');
                    
                    // 更新选择框
                    selectElement.innerHTML = '<option value="">请选择音频文件</option>' +
                        files.map(file => `<option value="${file.filename}">${file.filename}</option>`).join('');
                }
            } catch (error) {
                document.getElementById('audioFileList').innerHTML = `<p>加载失败: ${error.message}</p>`;
            }
        }
        
        // 选择文件进行测试
        function selectFileForTest(filename) {
            document.getElementById('testAudioFile').value = filename;
            
            // 尝试加载对应的期望文本
            const baseName = filename.replace(/\.[^/.]+$/, "");
            // 这里可以通过API获取对应的txt文件内容，简化起见先跳过
        }
        
        // 执行单个测试
        async function runSingleTest() {
            const audioFile = document.getElementById('testAudioFile').value;
            const expectedText = document.getElementById('testExpectedText').value;
            const chunkSize = parseInt(document.getElementById('chunkSize').value);
            const intervalMs = parseInt(document.getElementById('intervalMs').value);
            
            if (!audioFile) {
                alert('请选择音频文件');
                return;
            }
            
            if (!expectedText) {
                alert('请输入期望文本');
                return;
            }
            
            const testRequest = {
                audioFile: audioFile,
                expectedText: expectedText,
                chunkSize: chunkSize,
                intervalMs: intervalMs,
                timeoutSeconds: 30
            };
            
            try {
                showLoading(true);
                const response = await fetch(`${API_BASE}/run-single`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(testRequest)
                });
                
                const result = await response.json();
                displayTestResult([result]);
                
            } catch (error) {
                showResults([{
                    type: 'error',
                    title: '测试执行失败',
                    content: error.message
                }]);
            } finally {
                showLoading(false);
            }
        }
        
        // 执行预设测试
        async function runPresetTest() {
            try {
                showLoading(true);
                const response = await fetch(`${API_BASE}/run-preset`, {
                    method: 'POST'
                });
                
                const result = await response.json();
                
                if (result.results) {
                    displayBatchTestResult(result);
                } else {
                    showResults([{
                        type: 'error',
                        title: '预设测试失败',
                        content: '没有找到测试文件或执行失败'
                    }]);
                }
                
            } catch (error) {
                showResults([{
                    type: 'error',
                    title: '预设测试失败',
                    content: error.message
                }]);
            } finally {
                showLoading(false);
            }
        }
        
        // 显示单个测试结果
        function displayTestResult(results) {
            const resultsHtml = results.map(result => `
                <div class="test-result ${result.success ? 'success' : 'failure'}">
                    <h4>${result.success ? '✅' : '❌'} 测试结果: ${result.audioFile}</h4>
                    <p><strong>期望文本:</strong> ${result.expectedText}</p>
                    <p><strong>识别文本:</strong> ${result.actualText || '无结果'}</p>
                    <p><strong>置信度:</strong> ${result.confidence.toFixed(2)}</p>
                    <p><strong>测试状态:</strong> ${result.success ? '成功' : '失败'}</p>
                    <p><strong>音频时长:</strong> ${result.audioLength.toFixed(2)}秒</p>
                    <p><strong>测试用时:</strong> ${result.duration}ms</p>
                    ${result.errorMessage ? `<p><strong>错误信息:</strong> ${result.errorMessage}</p>` : ''}
                </div>
            `).join('');
            
            showResults([{
                type: 'info',
                title: '测试完成',
                content: resultsHtml
            }]);
        }
        
        // 显示批量测试结果
        function displayBatchTestResult(batchResult) {
            const summaryHtml = `
                <div class="test-result success">
                    <h4>📊 批量测试总结</h4>
                    <p><strong>总测试数:</strong> ${batchResult.totalTests}</p>
                    <p><strong>成功数:</strong> ${batchResult.successCount}</p>
                    <p><strong>失败数:</strong> ${batchResult.failureCount}</p>
                    <p><strong>成功率:</strong> ${(batchResult.successRate * 100).toFixed(1)}%</p>
                </div>
            `;
            
            const detailsHtml = batchResult.results.map(result => `
                <div class="test-result ${result.success ? 'success' : 'failure'}">
                    <h5>${result.success ? '✅' : '❌'} ${result.audioFile}</h5>
                    <p><strong>期望:</strong> ${result.expectedText}</p>
                    <p><strong>识别:</strong> ${result.actualText || '无结果'}</p>
                    <p><strong>置信度:</strong> ${result.confidence.toFixed(2)}</p>
                    <p><strong>用时:</strong> ${result.duration}ms</p>
                    ${result.errorMessage ? `<p><strong>错误:</strong> ${result.errorMessage}</p>` : ''}
                </div>
            `).join('');
            
            showResults([{
                type: 'info',
                title: '批量测试完成',
                content: summaryHtml + detailsHtml
            }]);
        }
        
        // 显示加载状态
        function showLoading(show) {
            document.getElementById('loading').style.display = show ? 'block' : 'none';
        }
        
        // 显示结果
        function showResults(results) {
            const resultsElement = document.getElementById('testResults');
            resultsElement.innerHTML = results.map(result => `
                <div class="results ${result.type}">
                    <h3>${result.title}</h3>
                    <div>${result.content}</div>
                </div>
            `).join('');
        }
        
        // 格式化文件大小
        function formatFileSize(bytes) {
            if (bytes === 0) return '0 Bytes';
            const k = 1024;
            const sizes = ['Bytes', 'KB', 'MB', 'GB'];
            const i = Math.floor(Math.log(bytes) / Math.log(k));
            return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
        }
    </script>
</body>
</html>
